<?php
	/**
	 * redis的kv缓存类，
	 * User: yxt
	 * Date: 2016/3/3
	 * Time: 14:14
	 */
	include_once dirname(__FILE__).DIRECTORY_SEPARATOR ."np_kv_cache.class.php" ;
	class np_kv_cache_redis_class extends np_kv_cache_class
	{
		private $int_default_connect_timeout=60;
		private static $arr_redis_connect=array();
		private $arr_config=array();
		private $arr_write_config=array();
		private $arr_read_config=array();

        private $zip_header= "ZIP##";

		/**
		 * 构造方法，暂时不支持使用hash
		 * np_kv_cache_redis_class constructor.
		 *
		 * @param $arr_config
		 */
		public function __construct( $arr_config )
		{
			$this->arr_config=$arr_config;

		}
		public function __destruct()
		{
			$this->_close();
		}

		/**
		 * open的时候不做任何操作，连接在写的时候去判断
		 * User: yxt
		 */
		public function open( )
		{


		}
		public function close()
		{
			$this->_close();
		}

		/**
		 * 2016年3月29日15:41:21
		 * 于小涛
		 * 获取hash写redis
		 * @param $str_key
		 *
		 * @return mixed
		 */
		private function __get_hash_write_redis($str_key)
		{
			$int_num=$this->__get_hash_service_group_num($str_key);
			$this->arr_write_config=$this->arr_config['servers'][$int_num]['write'];
			$str_write_key=md5($int_num.$this->arr_write_config['host'].$this->arr_write_config['port']);
			if(!isset(self::$arr_redis_connect[$str_write_key])||(empty(self::$arr_redis_connect[$str_write_key])))
			{
				self::$arr_redis_connect[$str_write_key] =new Redis();
				$bool_connect=self::$arr_redis_connect[$str_write_key]->connect($this->arr_write_config['host'],$this->arr_write_config['port'],$this->int_default_connect_timeout);
				if(isset($this->arr_write_config['password'])&&(strlen($this->arr_write_config['password'])>0))
				{
					$bool_connect=self::$arr_redis_connect[$str_write_key]->auth($this->arr_write_config['password']);
				}
			}
			if($bool_connect===false)
			{
				return false;
			}
			return self::$arr_redis_connect[$str_write_key];
		}
		/**
		 * 2016年3月29日15:41:21
		 * 于小涛
		 * 获取hash读redis
		 * @param $str_key
		 *
		 * @return mixed
		 */
		private function __get_hash_read_redis($str_key)
		{
			$int_num=$this->__get_hash_service_group_num($str_key);
			$int_read_num=array_rand($this->arr_config['servers'][$int_num]['read'],1);
			$this->arr_read_config=$this->arr_config['servers'][$int_num]['read'][$int_read_num];
			$str_read_key=md5($int_num.$this->arr_read_config['host'].$this->arr_read_config['port']);
			if(!isset(self::$arr_redis_connect[$str_read_key])||(empty(self::$arr_redis_connect[$str_read_key])))
			{
				self::$arr_redis_connect[$str_read_key] =new Redis();
				$bool_connect=self::$arr_redis_connect[$str_read_key]->connect($this->arr_read_config['host'],$this->arr_read_config['port'],$this->int_default_connect_timeout);
				if(isset($this->arr_read_config['password'])&&(strlen($this->arr_read_config['password'])>0))
				{
					$bool_connect=self::$arr_redis_connect[$str_read_key]->auth($this->arr_read_config['password']);
				}
			}
			if($bool_connect===false)
			{
				return false;
			}
			return self::$arr_redis_connect[$str_read_key];
		}

		/**
		 * 2016年3月29日15:31:10
		 * 于小涛
		 * 根据key获取redis对应的hash组，目前不支持hash，暂时都只返回第一个组
		 * @param $str_key 缓存key
		 * @return int $int_num
		 */
		private function __get_hash_service_group_num($str_key)
		{
			$int_num=0;
			return $int_num;
		}
		/**
		 * 保存
		 * @param $key key
		 * @param $value 值val
		 * @param int $expire 有效期，默认是5分钟，如果设置的时间小于1s，则按照5分钟存，如果设置的时间大于25小时，也按照25小时存
		 * @param null $ex_flag
		 *
		 * @return bool
		 */
		public function set($key, $value, $expire = 300, $ex_flag = NULL )
		{
//			$value=serialize($value);

            $value = $this->_zip_value($value);

			$expire=intval($expire);
			if($expire>10800)
			{
				$expire=10800;
			}
			if($expire<1)
			{
				$expire=300;
			}
			$arr_write_redis=$this->__get_hash_write_redis($key);
			$re=false;
			if(!empty($arr_write_redis))
			{
				$re=$arr_write_redis->setex($key,$expire,$value);
			}
			return $re;
		}

		/**
		 * 2016年3月29日15:49:34
		 * 于小涛
		 * 从读库获取缓存
		 * @param $str_key 缓存key
		 *
		 * @return mixed
		 */
		public function get( $str_key )
		{
			$arr_read_redis=$this->__get_hash_read_redis($str_key);
			if(empty($arr_read_redis))
			{
				return false;
			}
			$re=$arr_read_redis->get($str_key);
//			$re=unserialize($re);
            $re = $this->_unzip_value($re);
			return $re;
		}

		/**
		 * 2016年3月29日15:49:34
		 * 于小涛
		 * 从写库获取缓存
		 * @param $str_key 缓存key
		 *
		 * @return mixed
		 */
		public function get_in_set($str_key)
		{
			$arr_write_redis=$this->__get_hash_write_redis($str_key);
			$re=$arr_write_redis->get($str_key);
            $re = $this->_unzip_value($re);
//			$re=unserialize($re);
			return $re;
		}
		/**
		 * 2016年3月29日15:49:34
		 * 于小涛
		 * 删除缓存
		 * @param $str_key 缓存key
		 *
		 * @return mixed
		 */
		public function delete( $str_key )
		{
			$arr_write_redis=$this->__get_hash_write_redis($str_key);
			$re=$arr_write_redis->del($str_key);
			return $re;
		}

		/**
		 * 2016年3月29日15:50:28
		 * 于小涛
		 * 添加缓存
		 * @param $key 缓存key
		 * @param $value 缓存值
 		 * @param int $expire 缓存过期时间
		 * @param null $ex_flag
		 *
		 * @return bool
		 */
		public function add($key, $value, $expire = 0, $ex_flag = NULL )
		{
			return $this->set($key, $value, $expire, $ex_flag);

		}
		public function last_error_desc()
		{
		}
		public function get_type()
		{
		}
		private function _close()
		{
			if(is_array(self::$arr_redis_connect))
			{
				foreach(self::$arr_redis_connect as $obj_redis)
				{
					$obj_redis->close();
				}
			}
			self::$arr_redis_connect=null;
		}

        /**
         * 对字符串进行压缩，当字符串小于256，则不进行压缩
         * @param $value
         * @return string
         */
        private function _zip_value($value)
        {
            if (!is_array($value) && empty($value))
            {
                return $value;
            }
            $value = serialize($value);
            $len = strlen($value);
            if ($len > 256 && $this->kv_zip_enabled === true )
            {
                $zip_value = gzcompress($value);
                return  $this->zip_header.$zip_value;
            }
            return $value;
        }

        /**
         * 对字符串进行解压
         * @param $value
         * @return string
         */
        private function _unzip_value($value)
        {
            if (empty($value))
            {
                return $value;
            }

            if ($this->kv_zip_enabled === false)
            {
                return unserialize($value);
            }

            $zip_flag = substr($value,0,5);
            if ($zip_flag == $this->zip_header)
            {
                $zip_value = substr($value,5);
                return unserialize(gzuncompress($zip_value));
            }
            return unserialize($value);
        }

	}